package cn.topevery.garden.dal.logic.base;

import cn.topevery.garden.dal.dao.DeviceWarningDao;
import cn.topevery.garden.dal.logic.ExtentLogic;
import cn.topevery.garden.dal.logic.FacilitiesLogic;
import cn.topevery.garden.dal.logic.PersonLogic;
import cn.topevery.garden.dal.logic.warning.WxMessageService;
import cn.topevery.garden.entity.dto.UploadFileDTO;
import cn.topevery.garden.entity.po.DeviceWarning;
import cn.topevery.garden.entity.po.Extent;
import cn.topevery.garden.entity.query.DeviceWarningQuery;
import cn.topevery.garden.entity.vo.DeviceWarningVO;
import cn.topevery.garden.entity.vo.FacilitiesVO;
import cn.topevery.garden.framework.base.MsgParam;
import cn.topevery.garden.framework.util.DateUtils;
import cn.topevery.garden.framework.util.MsgUtils;
import hw.topevery.basis.dal.logic.SysClassExtLogic;
import hw.topevery.basis.dal.logic.SysClassLogic;
import hw.topevery.basis.entity.fetch.ClassFetch;
import hw.topevery.basis.entity.po.SysClass;
import hw.topevery.framework.db.entity.DataPager;
import hw.topevery.framework.dto.PointDto;
import hw.topevery.framework.map.CoordinateTransHelper;
import hw.topevery.framework.web.JsonResult;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ：peng.tian
 * @date ：Created in 2021/9/26 11:38
 * @description：预警基类
 */
@Slf4j
@Component
public abstract class WarningBase {

    @Autowired
    SysClassLogic sysClassLogic;

    @Autowired
    SysClassExtLogic sysClassExtLogic;

    @Autowired
    FacilitiesLogic facilitiesLogic;

//    @Autowired
//    private EventInfoManager eventInfoManager;

    @Autowired
    DeviceWarningDao deviceWarningDao;

    @Autowired
    private PersonLogic personLogic;

    @Autowired
    private WxMessageService wxMessageService;

    @Autowired
    private ExtentLogic extentLogic;

    /**
     * 获取类型表配置的预警项大类集合
     *
     * @返回值 预警项
     * @创建人 peng.tian
     * @创建时间 2021/9/26
     */
    public List<SysClass> getWarningItems() {
        List<SysClass> result = null;
        if (getClassId() != null) {
            ClassFetch fetch = new ClassFetch();
            fetch.setParentId(getClassId());
            result = sysClassLogic.getListClass(fetch);
        }
        return result;
    }

    public Double getValue(String classId) {
        return Double.parseDouble(sysClassExtLogic.getEntityByDataId(classId).unit);
    }

    /**
     * 获取属性名称和值
     */
    public Map getFiledsInfo(Object o) throws NoSuchFieldException, IllegalAccessException {
        Field[] fields = o.getClass().getDeclaredFields();
        String[] fieldNames = new String[fields.length];
        Map infoMap = new HashMap();
        for (int i = 0; i < fields.length; i++) {
            infoMap.put(fields[i].getName(), o.getClass().getField(fields[i].getName()).get(o));
        }
        return infoMap;
    }

    /**
     * 附件信息
     */
    public List<UploadFileDTO> uploadFileDTOS = null;

    private static final String typeId = "CBCBBFA8-C614-48AF-B719-630BF26D446C";//自动上报工单类型的一级id是固定的

    private HashMap<String, Integer> deviceTypeMapper = new HashMap() {
        {
            put("4ccc6c9a-80ae-4c03-be6d-23b22e13bb09", 3);
            put("d408daf6-1fc9-49a8-9927-ba53ff07a9f3", 7);
            put("23ace7c4-9123-44cf-91a1-7e546c5ea2f9", 8);
            put("7fbc583f-ee89-4e64-87d9-00e048581dab", 11);
            put("607f2817-192c-4630-be88-ec1d503d700e", 12);
            put("1cacd297-4f16-49fd-85e1-07d1d1959ce0", 13);
        }
    };

    private HashMap<String, String> facilitiesTypeMapper = new HashMap() {
        {
            put("4ccc6c9a-80ae-4c03-be6d-23b22e13bb09", "公厕");
            put("7fbc583f-ee89-4e64-87d9-00e048581dab", "水质水位");
            put("607f2817-192c-4630-be88-ec1d503d700e", "智能灌溉");
            put("23ace7c4-9123-44cf-91a1-7e546c5ea2f9", "井盖");
            put("d408daf6-1fc9-49a8-9927-ba53ff07a9f3", "分类垃圾桶");
            put("1cacd297-4f16-49fd-85e1-07d1d1959ce0", "河道监控");
        }
    };

    private HashMap<String, String> warningTypeMapper = new HashMap() {
        {
            put("89A7D7FA-9C39-4E94-8529-87A63CB7AA68", "公厕异常告警");
            put("8DBB25AC-5AC8-4EC6-B86F-90A7D6DB0BBB", "水质水位告警");
            put("2D37C78E-6748-4355-8672-570243957EB7", "智能灌溉告警");
            put("1E72EA75-D710-412B-BE6A-EC2C199C35AD", "井盖异常告警");
            put("46D152EA-8122-4D4C-90E8-8FDEA428A703", "垃圾桶异常告警");
            put("95B43414-47DB-4987-AC10-53C06485EF7E", "安全监控告警");
        }
    };

    private Map<String, String> bigClassTypeMap = new HashMap<String, String>() {
        {
            put("70C0BE95-2345-4D94-ABA9-E40DEE4D4AEA", "垃圾桶监管");
            put("7B4E7E50-E080-44FA-A0D7-786CFCF593BB", "井盖监管");
            put("B7A53505-04AF-4509-B10C-892C64234540", "水质水位监管");
            put("37F28D81-F37C-455E-BB21-054EEAF696DB", "智能公厕监管");
            put("2E2BEAAA-D00B-46B0-A4FC-DCC2FB59F935", "智能灌溉监管");
            put("B486F629-663C-48B4-B1CC-2131B3EE49AE", "智能监控预警");
        }
    };

    public String sendWarning(String code, String warningDesc, String facilitiesType, String facilitiesTypeName, String userId, String userName, String warningType, String warningName, Integer mainId) {

        FacilitiesVO facilities = facilitiesLogic.getByCodeAndType(code, deviceTypeMapper.get(facilitiesType));
        if (facilities == null) {
            log.error("基础设施信息中未找到当前设备，告警失败，设备编号：" + code + " 设施类别id：" + facilitiesType);
            return null;
        }
        if (facilities.getMapRangesPoints() == null) {
            log.error("基础设施信息中无坐标信息，告警失败，设备编号：" + code + " 设施类别id：" + facilitiesType);
            return null;
        }
        //如果当前设备30分钟内容上报过该类型的案件，并且还未处理则不继续产生案件
        DeviceWarningQuery deviceWarningQuery = new DeviceWarningQuery();
        deviceWarningQuery.setWarningStatus(0);
        deviceWarningQuery.setCode(code);
        deviceWarningQuery.setType(facilitiesType);
        deviceWarningQuery.setWarningTypeId(warningType);
        deviceWarningQuery.setMainId(mainId);
        DataPager<DeviceWarningVO> dataPager = deviceWarningDao.listPage(deviceWarningQuery);
        if (dataPager.records.size() > 0) {
            //  java.time.Duration duration = java.time.Duration.between(dataPager.records.get(0).getDbCreateDate(),LocalDateTime.now());
            // if(duration.toMinutes()<30) {
            //     log.info("当前设备30分钟内存在未处理的同类型预警案件,本此不产生新案件");
            //    return null;
            // }
            if (dataPager.records.get(0).getDbCreateDate().isAfter(LocalDate.now().atStartOfDay())) {
                log.info("当前设备一天内存在未处理的同类型预警案件,本此不产生新案件");
                return null;
            }
        }
//
//        SaveOrEditDTO param = new SaveOrEditDTO();
//        param.setUploadFiles(uploadFileDTOS);
//        param.setIndustryId("8756ff24-f536-44de-bf1f-bd67e7e57b69");//环卫行业
//        param.setDistrictId("CE54CE2A-FEB5-DD11-8009-001E90A20A0C");//深圳市
//        param.setStreetId("DEA065AB-2953-42E3-B16B-C9B2B4D16ADC");//南山区
//        param.setParkId(facilities.getParkId());
//        param.setExtentIdInt(facilities.getExtentId());
//        param.setExtentId(facilities.getExtentId() + "");
//        param.setTypeId(typeId);
//        param.setBigClassId(getClassId());//不同设备上报工单的bigClassId不同
//        param.setBigClass("设备设施");
//        param.setSmallClassId(this.getSmallClassId());//同一设备根据告警状态不同，上报工单的smallCassId不同
//        param.setSmallClass(warningName);
//        param.setAddress(facilities.getAddress());
//        param.setRemark(warningDesc);
//        param.setHandleLimit(72 * 60 * 60);//处理时限
//        param.setLngBd09(facilities.getMapRangesPoints().get(0).get(0).getLng());
//        param.setLatBd09(facilities.getMapRangesPoints().get(0).get(0).getLat());
//        if (param.getLngBd09() != null && param.getLatBd09() != null) {
//            PointDto pointDto = CoordinateTransHelper.bdDecrypt(facilities.getMapRangesPoints().get(0).get(0).getLng(), facilities.getMapRangesPoints().get(0).get(0).getLat());
//            param.setGeoX(pointDto.getLng());
//            param.setGeoY(pointDto.getLat());
//        }
//        param.setUserId(userId);
//        param.setUserName(userName);
//        param.setDeptId("835B6E1F-D9E7-42DB-A362-1317D8DBF8FB");
//        param.setMapType(13003);
//        param.setSourceId("86A7E5F6-A6E1-426C-8054-A0F22FD88CC7");//设备上报
//        JsonResult<String> result = eventInfoManager.saveWeChatEvt(param, false);
//        log.info("案件" + result.data + "已生成");
        DeviceWarning warning = new DeviceWarning();
        warning.setLng(facilities.getMapRangesPoints().get(0).get(0).getLng());
        warning.setLat(facilities.getMapRangesPoints().get(0).get(0).getLat());
        warning.setWarningStatus(0);
        warning.setMainId(mainId);
        warning.setDeviceCode(code);
        warning.setWarningDesc(warningDesc);
        warning.setType(facilitiesType);
        warning.setTypeName(facilitiesTypeName);
        warning.setWarningTypeId(warningType);
        warning.setWarningTypeName(warningName);
//        warning.setEventCode(result.data);
        deviceWarningDao.saveOrUpdate(userId, warning);
        //将消息推送至公众号
//        sendWxMessage(code, warningDesc, facilities, result);
        MsgParam msgParam = new MsgParam();
        //发送给片区所有人（需要openid不为空的对象）
        List<Map<String, Object>> openIds = personLogic.getOpenIdByExtentId(facilities.getExtentId());
        msgParam.setTemplateId("OYQxnycqFOjfh0TGWv18WRtf2iFlPYMktF5Tj9d6UcQ");
        msgParam.setPath("pages/index/index");
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        String date = dateFormat.format(new Date());
        openIds.forEach(item -> {
            log.info("向" + item.get("c_wx_ma_openid") + "推送信息");
            msgParam.setOpenid(String.valueOf(item.get("c_wx_ma_openid")));
            try {
                Map<String, String> map = new HashMap<String, String>() {
                    {
                        put("thing6", "设备告警工单");
                        put("thing2", facilities.getName());
                        put("thing3", "设备告警");
                        put("thing12", "设备告警，请处理");
                        put("time22", DateUtils.DateFormatFull(date));
                    }
                };
                msgParam.setParams(map);
                MsgUtils.sendTemplateMessage(msgParam);
            } catch (Exception e) {
                log.error(e.getMessage());
            }
        });
        return code;
    }

    private void sendWxMessage(String code, String warningDesc, FacilitiesVO facilities, JsonResult<String> result) {
        //将消息推送至公众号
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        Extent extent = extentLogic.getEntity(facilities.getExtentId());
        Map<String, String> message = new HashMap<String, String>() {
            {
//                put("first", extent.getName() + "片区设备编号为" + code + "的设备发出预警：\n" + warningDesc + "\n请工作人员前往" + facilities.getAddress() + "处理！");
                put("keyword1", result.data);//工单编号
//                put("keyword2", "智能预警/" + bigClass.name + "/" + smallClass.name);//工单类型
                put("keyword3", "管理员");//提交人
                put("keyword4", now.format(dateTimeFormatter));//提交时间
                put("keyword5", now.plusDays(3).format(dateTimeFormatter));//截止处理时间
            }
        };
        StringBuilder firstBuilder = new StringBuilder();
        if (extent != null) {
            firstBuilder.append(extent.getName()).append("片区");
        }
        if (StringUtils.isNotBlank(code)) {
            firstBuilder.append("设备编号为").append(code).append("的设备发出预警");
        }
        if (StringUtils.isNotBlank(warningDesc)) {
            firstBuilder.append("：\n").append(warningDesc);
        }
        if (StringUtils.isNotBlank(facilities.getAddress())) {
            firstBuilder.append("\n请工作人员前往").append(facilities.getAddress()).append("处理！");
        }
        message.put("first", firstBuilder.toString());
        StringBuilder keyword2Builder = new StringBuilder();
        keyword2Builder.append("智能预警");
        if (StringUtils.isNotBlank(getClassId())) {
            SysClass bigClass = sysClassLogic.getEntityByDataId(getClassId());
            if (bigClass != null) {
                keyword2Builder.append("/").append(bigClass.name);
            }
        }
        if (StringUtils.isNotBlank(this.getSmallClassId())) {
            SysClass smallClass = sysClassLogic.getEntityByDataId(this.getSmallClassId());
            if (smallClass != null) {
                keyword2Builder.append("/").append(smallClass.name);
            }
        }
        message.put("keyword2", keyword2Builder.toString());
        wxMessageService.sendTemplateMessage(message);
        log.info("工单：{}消息已推送至公众号", result.data);
    }

    public String sendWarning(String code, String warningDesc, Integer mainId) {
        String userId = "1",
                userName = "管理员",
                facilitiesTypeName = facilitiesTypeMapper.get(getFacilitiesType()),
                warningName = warningTypeMapper.get(getWarningType());
        return this.sendWarning(code, warningDesc, getFacilitiesType(), facilitiesTypeName, userId, userName, getWarningType(), warningName, mainId);
    }

    /**
     * 预警类别id
     *
     * @返回值 预警类别id
     * @创建人 peng.tian
     * @创建时间 2021/9/26
     */
    public abstract String getClassId();//相当于bigClassId

    /**
     * 设施类型
     *
     * @创建人 peng.tian
     * @创建时间 2021/9/26
     */
    public abstract String getFacilitiesType();

    /**
     * 预警类型
     *
     * @创建人 peng.tian
     * @创建时间 2021/9/26
     */
    public abstract String getWarningType();//用于关联不同设备警告对应的描述描述

    @Getter
    @Setter
    private String smallClassId;
}
